//
//  TuJiaAutoLayoutPopupView.swift
//  PMSBase
//
//  Created by WangWenhui on 2017/5/5.
//  Copyright © 2017年 TuJia. All rights reserved.
//

import Foundation

public class TuJiaAutoLayoutPopupView : TPKeyboardAvoidingScrollView {
    public static let contentFixedWidth : CGFloat = 300
    
    public let view : UIView
    // 当点击阴影时，是否附加最左侧按钮的点击事件。默认不会附加。
    public var attachActionWhileHiddenCauseByMaskTouched = false
    // 当点击阴影时，是否执行隐藏逻辑，默认为true。如果设置了false，attachActionWhileHiddenCauseByMaskTouched将无效
    public var enableHiddenByMaskTouched = true
    // container for view and buttons.
    fileprivate lazy var container: UIView = {
        // container for UIScrollView's content.
        let view = UIView()
        self.addSubview(view)
        view.snp.makeConstraints({ (make) in
            make.edges.equalTo(self)
        })
        return view
    }()
    fileprivate var contentView : UIView! // content container which will add view from outside.
    fileprivate var buttons : [(btn:UIButton,action:(()->Bool)?)]!
    fileprivate var bottomView : UIView!
    fileprivate var isAnimation : Bool = false
    fileprivate var controller : UIViewController? // todo: 可能引起循环引用
    
    // layout|event delegate
    public weak var layoutDelegate: TuJiaAutoLayoutPopupViewLayoutDelegate?
    public weak var eventDelegate: TuJiaAutoLayoutPopupViewEventDelegate?
    
    public convenience init(view: UIView, item: String, action: (()->Bool)? = nil) {
        self.init(view: view, buttons: [(item, action,MutexColors.PopConfirm)])
    }
    
    public convenience init(view: UIView, left: String, leftAction: (()->Bool)?, right: String, rightAction: (()->Bool)?) {
        self.init(view: view, buttons: [(left, leftAction, MutexColors.PopCancel), (right, rightAction, MutexColors.PopConfirm)])
    }
    
    /**
     Init tujia popview.
     
     - parameter view:    content view.
     - parameter buttons: button info.
     - note : text is button title string.
     - note : action is button touched action, return boolean to decide hide popview or not.
     - note : color is button colors.
     
     - returns: popview.
     */
    public init(view : UIView, layout: TuJiaAutoLayoutPopupViewLayouts.EnumLayoutStyle = .center, buttons : [(text: String, action:(()->Bool)?, color: MutexColor)]?) {
        self.layoutDelegate = TuJiaAutoLayoutPopupViewLayouts.getLayoutDelegate(layout)
        self.view = view
        super.init(frame: UIScreen.main.bounds)
        self.backgroundColor = UIColor(white: 0.0, alpha: 0.5)
        
        self.buttons = []
        if buttons != nil {
            for item in buttons! {
                let button = VS.makeButton(VS.font16, item.text, item.color)
                button.setBackgroundColor(VS.sepPageGray, forState: .highlighted)
                button.addTarget(self, action: #selector(TuJiaAutoLayoutPopupView.onPopupViewButtonTouched(_:)), for: .touchUpInside)
                self.buttons.append((button, item.action))
            }
        }
        render()
    }
    
    public convenience init(controller : UIViewController, buttons : [(text: String, action:(()->Bool)?, color: MutexColor)]?) {
        self.init(view: controller.view, buttons: buttons)
        self.controller = controller
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    fileprivate func render() {
        //subviews
        contentView = UIView()
        container.addSubview(contentView)
        
        contentView.addSubview(view)
        view.backgroundColor = UIColor.white
        
        if buttons.count > 0 {
            // sepcial separator
            let sep = UIView()
            sep.backgroundColor = VS.sepControlGray
            sep.alpha = 0.8
            contentView.addSubview(sep)
            sep.snp_makeConstraintsDynamic(closure: { (make) in
                make.height.equalTo(CommonDefine.kPixel)
                make.top.equalTo(view.snp.bottom)
                make.left.right.equalTo(contentView)
            })
            bottomView = UIView()
            bottomView.backgroundColor = UIColor.white
            contentView.addSubview(bottomView)
            
            var lastBtn : UIButton?
            for btnInfo in self.buttons {
                bottomView.addSubview(btnInfo.btn)
                btnInfo.btn.snp.updateConstraints({ (make) in
                    make.bottom.equalTo(bottomView)
                    make.left.equalTo(lastBtn == nil ? bottomView.snp.left : lastBtn!.snp.right)
                    make.height.equalTo(bottomView).offset(-CommonDefine.kPixel)
                    make.width.equalTo(bottomView).dividedBy(self.buttons.count)
                })
                lastBtn = btnInfo.btn
            }
            
            for index in 1..<self.buttons.count {
                let btnSep = VS.makeSeparator()
                let btn = self.buttons[index].btn
                btn.addSubview(btnSep)
                btnSep.snp.updateConstraints({ (make) in
                    make.width.equalTo(CommonDefine.kPixel)
                    make.left.centerY.equalTo(btn)
                    make.height.equalTo(btn).multipliedBy(0.5)
                })
            }
            
            bottomView.snp.makeConstraints({ (make) in
                make.left.right.equalTo(contentView)
                make.top.equalTo(sep.snp.bottom)
                make.height.equalTo(48)
            })
        }
        
        // autolayout controls.
        view.snp.makeConstraints { (make) in
            make.left.top.right.equalTo(contentView)
        }
        
        layoutDelegate?.settingForPopupContentView(contentView, lastContentView: bottomView ?? view)
    }
    
    fileprivate func resetContainerDynamicLayout(_ isHide: Bool) {
        
        layoutDelegate?.settingForPopupAnimationDynamicConstaints(contentView, isHide: isHide)
    }
    
    @objc public func onPopupViewButtonTouched(_ sender: UIButton) {
        if self.buttons.first({ $0.btn == sender })?.action?() ?? true {
            self.hide()
        }
    }
    
    public func show() {
        let win = UIApplication.shared.keyWindow
        if win != nil && win != self.superview {
            win?.addSubview(self)
            container.snp.updateConstraints({ (make) in
                make.width.equalTo(win!.bounds.width)
                make.height.equalTo(win!.bounds.height)
            })
        }
        isAnimation = true
        if let ctrl = self.controller {
            if let currentCtrl = win?.getViewController() {
                currentCtrl.addChild(ctrl)
                ctrl.didMove(toParent: currentCtrl)
            }
        }
        
        resetContainerDynamicLayout(true)
        self.layoutIfNeeded()
        UIView.animate(withDuration: 0.8, delay: 0.1, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: UIView.AnimationOptions.curveEaseIn, animations: { () -> Void in
            self.alpha = 1
            self.resetContainerDynamicLayout(false)
            self.layoutIfNeeded()
        }) { _ in
            self.isAnimation = false
            self.eventDelegate?.onPopupViewShowAnimationCompletion?(self)
        }
    }
    
    public func hide() {
        self.endEditing(true)
        
//        UIView.animate(withDuration: 0.4, animations: { () -> Void in
//            self.resetContainerDynamicLayout(true)
//            self.layoutIfNeeded()
//        })
        
        UIView.animate(withDuration: 0.3, delay: 0.4, options: UIView.AnimationOptions(), animations: { () -> Void in
            self.alpha = 0.0
        }) { (done) -> Void in
            self.resetContainerDynamicLayout(true)
            self.layoutIfNeeded()
            self.removeFromSuperview()
            self.alpha = 1.0;
            self.controller?.removeFromParent()
            self.controller = nil
            self.eventDelegate?.onPopupViewHideAnimationCompletion?(self)
        }
    }
    
    override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if(!isAnimation && enableHiddenByMaskTouched) {
            let touchView = self.hitTest(((touches as NSSet).anyObject()! as AnyObject).location(in: self), with: event)
            if (touchView == self || touchView == self.container) {
                if let btn = self.buttons.first, self.attachActionWhileHiddenCauseByMaskTouched {
                    onPopupViewButtonTouched(btn.btn)
                } else {
                    self.hide()
                }
            }
        }
    }
    
    public func resetSize(_ duration: Double = 0.4) {
        UIView.animate(withDuration: duration, animations: {
            self.layoutIfNeeded()
        })
    }
}

// MARK: - Alert & Confirm
extension TuJiaAutoLayoutPopupView {
    
    // MARK: help view
    public class func showAlert(_ title: String? = nil, text: String, align: NSTextAlignment = .center, cancelItem : String = NSLocalizedString("确定", comment: "./PMS/Classes/Views/PMSPopupView.swift"), cancelAction: (()->Bool)? = nil) {
        let view = createMessageView(title, text, align)
        let pop = TuJiaAutoLayoutPopupView(view: view, item: cancelItem, action: cancelAction)
        pop.show()
    }
    
    public class func showConfirm(_ title: String? = nil, text: String, cancelItem: String = NSLocalizedString("取消", comment: "./PMS/Classes/Views/PMSPopupView.swift"), cancelAction: (()->Bool)? = nil, confirmItem: String = NSLocalizedString("确定", comment: "./PMS/Classes/Views/PMSPopupView.swift"), confirmAction: @escaping ()->Bool) {
        let view = createMessageView(title, text, .center)
        let pop = TuJiaAutoLayoutPopupView(view: view, left: cancelItem, leftAction: cancelAction, right: confirmItem, rightAction: confirmAction)
        pop.show()
    }
    
    fileprivate class func createMessageView(_ title: String? = nil, _ text: String, _ align: NSTextAlignment) -> UIView {
        let content = UIView()
        let lbl = VS.makeLabel(VS.font16, VS.txtMain, align)
        lbl.numberOfLines = 0
        content.addSubview(lbl)
        lbl.snp.updateConstraints { (make) in
            make.center.equalTo(content)
            make.left.greaterThanOrEqualTo(content).offset(VS.margin15)
            make.right.lessThanOrEqualTo(content).offset(-VS.margin15)
            make.top.equalTo(content).offset(VS.margin15*2)
        }
        lbl.text = text
        
        if title != nil && !title!.isEmpty {
            let lblTitle = VS.makeLabel(UIFont.boldSystemFont(ofSize: 16), UIColor.black, .center)
            lblTitle.text = title
            lblTitle.withBottomSeparater(space: 0)
            let view = UIView()
            view.addSubview(lblTitle)
            view.addSubview(content)
            lblTitle.snp.updateConstraints({ (make) in
                make.left.right.equalTo(view)
                make.height.equalTo(44)
                make.top.equalTo(view)
            })
            content.snp.updateConstraints({ (make) in
                make.left.right.equalTo(view)
                make.bottom.equalTo(view)
                make.top.equalTo(lblTitle.snp.bottom)
            })
            
            return view
        }
        
        return content
    }
}
